﻿namespace OverStore.Runtime.Storage
{
    using System.Collections.Generic;
    using OverStore.Scoping;
using OverStore.Sql;

    /// <summary>
    /// Read or write data to data storage using <see cref="ICommand"/> objects for 
    /// describe action to perform on storage.
    /// </summary>
    public interface IDataStorage : IRuntimeComponent
    {
        /// <summary>
        /// Gets the SQL formatting used for generate SQL commands using table schema or null if storage is not SQL based storage or 
        /// it does not support generated SQL.
        /// </summary>
        SqlFormatting SqlFormatting { get; }

        /// <summary>
        /// Executes specified command against data storage and returns <see cref="TypedRecord"/>
        /// contains execution result. The method how the command result is obtained is specified for 
        /// <see cref="AdoNetStorage{TConnection}"/>
        /// </summary>
        /// <param name="command">The command for data storage.</param>
        /// <param name="parameters">The parameters for command.</param>
        /// <param name="rowsAffected">Number of rows affected by command execution.</param>
        /// <returns>The <see cref="IRecord"/> instance contains values of parameters possible modified during command execution.</returns>
        /// <exception cref="PersistingRuntimeException">Error occurs during command executing.</exception>
        TypedRecord Execute(ICommand command, IRecord parameters, out int rowsAffected);

        /// <summary>
        /// Executes specified command and read all data from result set returned.
        /// </summary>
        /// <param name="command">The command.</param>
        /// <param name="parameters">The parameters.</param>
        /// <exception cref="PersistingRuntimeException">Error occurs during command executing.</exception>
        IEnumerable<TypedRecord> ReadAll(ICommand command, IRecord parameters);

        /// <summary>
        /// Gets <c>true</c> if instance was disposed, <c>false</c> otherwise.
        /// </summary>
        bool Disposed { get; }

        /// <summary>
        /// Starts new operation scope.
        /// </summary>
        OperationScope OpenScope();
    }
}